﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using Google.GData.Analytics;
using Google.GData.Extensions;
using System.Windows.Xps;
using System.Windows.Xps.Serialization;
using System.Windows.Xps.Packaging;
using System.IO.Packaging;
using System.IO;
using System.Windows.Markup;
using Visifire.Charts;
using Visifire.Commons;
using System.Printing;
using System.Windows.Controls.Primitives;
using System.Collections;
using System.Collections.ObjectModel;

namespace GoogleAnalyticsReport
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private AnalyticsService service = new AnalyticsService("AnalyticsSvc");
        private Collection<ProfileItem> Profiles = new Collection<ProfileItem>();
        private const string dataFeedUrl = "https://www.google.com/analytics/feeds/data";
        private ArrayList PageCounts = new ArrayList();
        private FixedDocument fixDoc = null;
        Random rnd = new Random();

        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            StartDateDatepicker.SelectedDate = DateTime.Now.AddMonths(-1).Date;
            EndDateDatepicker.SelectedDate = DateTime.Now.AddDays(-1).Date;
            ProfileListView.DataContext = Profiles;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Expander1.IsExpanded = false;
            AccountQuery query = new AccountQuery();
            
            if (!string.IsNullOrEmpty(UserNameTextbox.Text))
            {
                service.setUserCredentials(UserNameTextbox.Text, PasswordTextbox.Text);
            }

            AccountFeed accountFeed = service.Query(query);
            Profiles.Clear();
            foreach (AccountEntry entry in accountFeed.Entries)
            {
                ProfileItem item = new ProfileItem();
                item.Title = entry.Title.Text;
                item.ProfileID = entry.ProfileId.Value;
                Profiles.Add(item);
                GenReportButton.IsEnabled = Profiles.Count > 0;
                Expander1.IsExpanded = true;
            }
        }

        private Canvas AddPage(FixedDocument doc,DateTime StartDate, DateTime EndDate)
        {
            DocumentPaginator paginator = doc.DocumentPaginator;
            FixedPage page = new FixedPage();

            PageContent pageContent = new PageContent();
            (pageContent as IAddChild).AddChild(page);
            doc.Pages.Add(pageContent);

            Canvas content = new Canvas();
            page.Children.Add(content);
            AddHeaderAndFooter(doc.Pages.Count, 50, content, paginator, StartDate, EndDate);

            return content;
        }

        void AddHeaderAndFooter(int pageNo, int headerFooterHeight, 
            Canvas pageCanvas, DocumentPaginator paginator,
            DateTime startDate, DateTime endDate
            )
        {
            Image logoPic = new Image();
            logoPic.Source = new BitmapImage(new Uri("analytics_logo.JPG", UriKind.Relative));
            Canvas.SetTop(logoPic, 30);
            Canvas.SetLeft(logoPic, 50);
            pageCanvas.Children.Add(logoPic);

            TextBlock webName = new TextBlock();
            webName.Text = " - www.utan.com";
            webName.FontFamily = new System.Windows.Media.FontFamily("Arial");
            webName.FontSize = 26;
            webName.Foreground = new SolidColorBrush(Color.FromRgb(127, 127, 127));
            Canvas.SetLeft(webName, 50 + 213);
            Canvas.SetTop(webName, 33);
            pageCanvas.Children.Add(webName);

            TextBlock timeLine = new TextBlock();
            timeLine.Text = "自" + startDate.ToShortDateString() + " 至" + endDate.ToShortDateString();
            timeLine.FontFamily = new System.Windows.Media.FontFamily("微软雅黑");
            timeLine.FontSize = 18;
            timeLine.Foreground = new SolidColorBrush(Color.FromRgb(127, 127, 127));
            Canvas.SetLeft(timeLine, 50);
            Canvas.SetTop(timeLine, 70);
            pageCanvas.Children.Add(timeLine);

            TextBlock footer = new TextBlock();
            footer.Text += "第" + pageNo + "页";
            footer.TextAlignment = TextAlignment.Center;
            footer.FontFamily = new System.Windows.Media.FontFamily("微软雅黑");
            footer.Width = paginator.PageSize.Width;
            Canvas.SetTop(footer, paginator.PageSize.Height - headerFooterHeight);
            pageCanvas.Children.Add(footer);
        }

        void OutPutXPS(FixedDocument doc)
        {
            PrintDocumentImageableArea imageArea = null;
            XpsDocumentWriter xpsdw = PrintQueue.CreateXpsDocumentWriter(ref imageArea);
            if (xpsdw != null)
            {
                xpsdw.Write(doc);
            }
        }

        private void GenReportButton_Click(object sender, RoutedEventArgs e)
        {
            if (ProfileListView.SelectedIndex == -1)
                ProfileListView.SelectedIndex = 0;
            ProfileItem selectedProfile = (ProfileItem)ProfileListView.SelectedItem;
            
            fixDoc = new FixedDocument();
            DateTime StartDate = StartDateDatepicker.SelectedDate.Value;
            DateTime EndDate = EndDateDatepicker.SelectedDate.Value;
            if (StartDate.DayOfWeek != 0)
                StartDate = StartDate.AddDays(DayOfWeek.Sunday - StartDate.DayOfWeek);

            Canvas page1 = AddPage(fixDoc, 
                StartDate, EndDate);

            PrintVisits(page1, selectedProfile.ProfileID, 
                StartDate, EndDate);

            PrintPageviews(page1, selectedProfile.ProfileID, 
                StartDate, EndDate);

            PrintPageCount(page1, selectedProfile.ProfileID, 
                StartDate, EndDate);

            PrintBounces(page1, selectedProfile.ProfileID, 
                StartDate, EndDate);

            PrintTimeOnSite(page1, selectedProfile.ProfileID, 
                StartDate, EndDate);

            Canvas page2 = AddPage(fixDoc, StartDate, EndDate);
            PrintUserCount(page2, selectedProfile.ProfileID,
                StartDate, EndDate);

            PrintBrowser(page2, selectedProfile.ProfileID,
                StartDate, EndDate);

            //PrintIEBrowser(page2, selectedProfile.ProfileID,
            //    StartDate, EndDate);

            PrintPagePath(page2, selectedProfile.ProfileID, 
                StartDate, EndDate);

            OutPutXPS(fixDoc);
        }

        private Chart CreateChart()
        {
            // 生成图表
            Chart chart = new Chart();
            chart.Width = 750;
            chart.Height = 150;
            chart.AnimationEnabled = false;
            chart.Bevel = false;

            // Set axis properties
            Axis axis = new Axis();
            axis.IntervalType = IntervalTypes.Weeks;
            axis.Interval = 1;
            axis.StartFromZero = true;

            ChartGrid chartGrid = new ChartGrid();
            chartGrid.Enabled = true;
            axis.Grids.Add(chartGrid);
            chart.AxesX.Add(axis);

            DataSeries dataSeries = new DataSeries();
            dataSeries.RenderAs = RenderAs.Line;
            chart.Series.Add(dataSeries);

            string[] colorSets = new string[] { "VisiRed", "VisiOrange", "VisiGreen", "VisiBlue" };
            chart.ColorSet = colorSets[rnd.Next(colorSets.Length)];

            return chart;
        }

        private Chart CreateColumnChart()
        {
            // 生成图表
            Chart chart = new Chart();
            chart.Width = 750;
            chart.Height = 150;
            chart.AnimationEnabled = false;
            chart.Bevel = false;

            DataSeries dataSeries = new DataSeries();
            dataSeries.RenderAs = RenderAs.Column;
            chart.Series.Add(dataSeries);

            return chart;
        }

        private Chart CreatePieChart()
        {
            // 生成图表
            Chart chart = new Chart();
            chart.Width = 750;
            chart.Height = 200;
            chart.AnimationEnabled = false;
            //chart.Bevel = false;

            DataSeries dataSeries = new DataSeries();
            dataSeries.RenderAs = RenderAs.Pie;
            dataSeries.YValueFormatString = "#0.##%";
            chart.Series.Add(dataSeries);

            return chart;
        }

        private void PrintVisits(Canvas pageCanvas, string profileId, DateTime startDate, DateTime endDate)
        {
            Chart chart = CreateChart();
            //chart.ColorSet = "VisiRed";

            Title title = new Title();
            title.Text = "访问者";
            chart.Titles.Add(title);
            
            DataPoint dataPoint;
            DataSeries dataSeries = chart.Series[0];

            // 生成查询
            DataQuery query = new DataQuery(dataFeedUrl);
            query.Ids = profileId;
            query.Metrics = "ga:visits";
            query.Dimensions = "ga:date";
            query.Sort = "ga:date";
            query.GAStartDate = startDate.ToString("yyyy-MM-dd");
            query.GAEndDate = endDate.ToString("yyyy-MM-dd");

            DataFeed dataFeed = service.Query(query);
            PageCounts.Clear();
            foreach (DataEntry entry in dataFeed.Entries)
            {
                dataPoint = new DataPoint();
                dataPoint.YValue = Convert.ToDouble(entry.Metrics[0].Value);
                PageCounts.Add(dataPoint.YValue);
                string dt = entry.Dimensions[0].Value;
                dataPoint.XValue = dt.Substring(4, 2) + "月" + dt.Substring(6, 2) + "日";
                dataSeries.DataPoints.Add(dataPoint);
            }
            
            // Add dataSeries to Series collection.
            

            // Add chart to LayoutRoot
            Canvas.SetLeft(chart, 50);
            Canvas.SetTop(chart, 100);
            pageCanvas.Children.Add(chart);
        }

        private void PrintPageviews(Canvas pageCanvas, string profileId, DateTime startDate, DateTime endDate)
        {
            // 生成图表
            Chart chart = CreateChart();

            Title title = new Title();
            title.Text = "综合浏览量";
            chart.Titles.Add(title);

            DataPoint dataPoint;
            DataSeries dataSeries = chart.Series[0];

            // 生成查询
            DataQuery query = new DataQuery(dataFeedUrl);
            query.Ids = profileId;
            query.Metrics = "ga:pageviews";
            query.Dimensions = "ga:date";
            query.Sort = "ga:date";
            query.GAStartDate = startDate.ToString("yyyy-MM-dd");
            query.GAEndDate = endDate.ToString("yyyy-MM-dd");

            int i = 0;
            DataFeed dataFeed = service.Query(query);
            foreach (DataEntry entry in dataFeed.Entries)
            {
                dataPoint = new DataPoint();
                dataPoint.YValue = Convert.ToDouble(entry.Metrics[0].Value);
                PageCounts[i] = dataPoint.YValue / Convert.ToDouble(PageCounts[i]);
                string dt = entry.Dimensions[0].Value;
                dataPoint.XValue = dt.Substring(4, 2) + "月" + dt.Substring(6, 2) + "日";
                dataSeries.DataPoints.Add(dataPoint);
                ++i;
            }

            // Add chart to LayoutRoot
            Canvas.SetLeft(chart, 50);
            Canvas.SetTop(chart, 260);
            pageCanvas.Children.Add(chart);
        }

        private void PrintPageCount(Canvas pageCanvas, string profileId, DateTime startDate, DateTime endDate)
        {
            // 生成图表
            Chart chart = CreateChart();
            //chart.ColorSet = "VisiOrange";

            Title title = new Title();
            title.Text = "每次访问页数";
            chart.Titles.Add(title);

            DataPoint dataPoint;
            DataSeries dataSeries = chart.Series[0];

            DateTime dt = startDate;
            foreach (Object obj in PageCounts)
            {
                dataPoint = new DataPoint();
                dataPoint.YValue = Convert.ToDouble(obj);
                dataPoint.XValue = dt;
                dataSeries.DataPoints.Add(dataPoint);
                dt = dt.AddDays(1);
            }

            // Add chart to LayoutRoot
            Canvas.SetLeft(chart, 50);
            Canvas.SetTop(chart, 420);
            pageCanvas.Children.Add(chart);
        }

        void PrintBounces(Canvas pageCanvas, string profileId, DateTime startDate, DateTime endDate)
        {
            // 生成图表
            Chart chart = CreateChart();
 
            Title title = new Title();
            title.Text = "跳出率";
            chart.Titles.Add(title);

            DataSeries dataSeries = chart.Series[0];
            DataPoint dataPoint;

            // 生成查询
            DataQuery query = new DataQuery(dataFeedUrl);
            query.Ids = profileId;
            query.Metrics = "ga:bounces,ga:entrances";
            query.Dimensions = "ga:date";
            query.Sort = "ga:date";
            query.GAStartDate = startDate.ToString("yyyy-MM-dd");
            query.GAEndDate = endDate.ToString("yyyy-MM-dd");

            int i = 0;
            DataFeed dataFeed = service.Query(query);
            foreach (DataEntry entry in dataFeed.Entries)
            {
                dataPoint = new DataPoint();
                dataPoint.YValue = Convert.ToDouble(entry.Metrics[0].Value) / Convert.ToDouble(entry.Metrics[1].Value);
                string dt = entry.Dimensions[0].Value;
                dataPoint.XValue = dt.Substring(4, 2) + "月" + dt.Substring(6, 2) + "日";
                dataSeries.DataPoints.Add(dataPoint);
                ++i;
            }

            // Add chart to LayoutRoot
            Canvas.SetLeft(chart, 50);
            Canvas.SetTop(chart, 580);
            pageCanvas.Children.Add(chart);
        }

        void PrintTimeOnSite(Canvas pageCanvas, string profileId, DateTime startDate, DateTime endDate)
        {
            // 生成图表
            Chart chart = CreateChart();
            //chart.ColorSet = "VisiGreen";
            Title title = new Title();
            title.Text = "平均网站停留时间(单位:秒)";
            chart.Titles.Add(title);

            DataSeries dataSeries = chart.Series[0];
            dataSeries.YValueFormatString = "hh:mm::ss";
            DataPoint dataPoint;

            // 生成查询
            DataQuery query = new DataQuery(dataFeedUrl);
            query.Ids = profileId;
            query.Metrics = "ga:timeOnSite,ga:visits";
            query.Dimensions = "ga:date";
            query.Sort = "ga:date";
            query.GAStartDate = startDate.ToString("yyyy-MM-dd");
            query.GAEndDate = endDate.ToString("yyyy-MM-dd");

            int i = 0;
            DataFeed dataFeed = service.Query(query);
            foreach (DataEntry entry in dataFeed.Entries)
            {
                dataPoint = new DataPoint();
                int t = Convert.ToInt32(Convert.ToDouble(entry.Metrics[0].Value) / Convert.ToDouble(entry.Metrics[1].Value));
                dataPoint.YValue = t; // new TimeSpan(t / 3600, (t / 60) % 60, t % 60);
                string dt = entry.Dimensions[0].Value;
                dataPoint.XValue = dt.Substring(4, 2) + "月" + dt.Substring(6, 2) + "日";
                dataSeries.DataPoints.Add(dataPoint);
                ++i;
            }

            // Add chart to LayoutRoot
            Canvas.SetLeft(chart, 50);
            Canvas.SetTop(chart, 740);
            pageCanvas.Children.Add(chart);
        }

        void PrintUserCount(Canvas pageCanvas, string profileId, DateTime startDate, DateTime endDate)
        {
            // 生成图表
            Chart chart = CreateChart();
            //chart.ColorSet = "VisiRed";
            Title title = new Title();
            title.Text = "绝对唯一访问者人数";
            chart.Titles.Add(title);

            DataSeries dataSeries = chart.Series[0];
            DataPoint dataPoint;

            // 生成查询
            DataQuery query = new DataQuery(dataFeedUrl);
            query.Ids = profileId;
            query.Metrics = "ga:visitors";
            query.Dimensions = "ga:date";
            query.Sort = "ga:date";
            query.GAStartDate = startDate.ToString("yyyy-MM-dd");
            query.GAEndDate = endDate.ToString("yyyy-MM-dd");

            int i = 0;
            DataFeed dataFeed = service.Query(query);
            foreach (DataEntry entry in dataFeed.Entries)
            {
                dataPoint = new DataPoint();
                dataPoint.YValue = Convert.ToDouble(entry.Metrics[0].Value);
                string dt = entry.Dimensions[0].Value;
                dataPoint.XValue = dt.Substring(4, 2) + "月" + dt.Substring(6, 2) + "日";
                dataSeries.DataPoints.Add(dataPoint);
                ++i;
            }

            // Add chart to LayoutRoot
            Canvas.SetLeft(chart, 50);
            Canvas.SetTop(chart, 100);
            pageCanvas.Children.Add(chart);
        }

        void PrintBrowser(Canvas pageCanvas, string profileId, DateTime startDate, DateTime endDate)
        {
            // 生成图表
            Chart chart = CreateColumnChart();
            //chart.ColorSet = "VisiRed";
            Title title = new Title();
            title.Text = "浏览器";
            chart.Titles.Add(title);

            DataSeries dataSeries = chart.Series[0];
            DataPoint dataPoint;

            // 生成查询
            DataQuery query = new DataQuery(dataFeedUrl);
            query.Ids = profileId;
            query.Metrics = "ga:visits";
            query.Dimensions = "ga:browser";
            query.Sort = "-ga:visits,ga:browser";
            query.GAStartDate = startDate.ToString("yyyy-MM-dd");
            query.GAEndDate = endDate.ToString("yyyy-MM-dd");

            int i = 0;
            DataFeed dataFeed = service.Query(query);
            foreach (DataEntry entry in dataFeed.Entries)
            {
                dataPoint = new DataPoint();
                dataPoint.YValue = Convert.ToDouble(entry.Metrics[0].Value);
                dataPoint.AxisXLabel = entry.Dimensions[0].Value;
                dataSeries.DataPoints.Add(dataPoint);
                if (++i >= 10)
                    break;
            }

            // Add chart to LayoutRoot
            Canvas.SetLeft(chart, 50);
            Canvas.SetTop(chart, 260);
            pageCanvas.Children.Add(chart);
        }

        void PrintIEBrowser(Canvas pageCanvas, string profileId, DateTime startDate, DateTime endDate)
        {
            // 生成图表
            Chart chart = CreatePieChart();
            //chart.ColorSet = "VisiRed";
            Title title = new Title();
            title.Text = "IE浏览器";
            chart.Titles.Add(title);

            DataSeries dataSeries = chart.Series[0];
            DataPoint dataPoint;

            // 生成查询
            DataQuery query = new DataQuery(dataFeedUrl);
            query.Ids = profileId;
            query.Metrics = "ga:visits";
            query.Dimensions = "ga:browser,ga:browserVersion";
            query.Sort = "-ga:visits,ga:browser,ga:browserVersion";
            query.Filters = "ga:browser==Internet Explorer";
            query.GAStartDate = startDate.ToString("yyyy-MM-dd");
            query.GAEndDate = endDate.ToString("yyyy-MM-dd");

            int i = 0;
            DataFeed dataFeed = service.Query(query);
            double sum = 0;
            foreach (DataEntry entry in dataFeed.Entries)
            {
                sum += Convert.ToDouble(entry.Metrics[0].Value);
            }

            foreach (DataEntry entry in dataFeed.Entries)
            {
                dataPoint = new DataPoint();
                dataPoint.YValue = Convert.ToDouble(entry.Metrics[0].Value) / sum;
                dataPoint.AxisXLabel = entry.Dimensions[1].Value;
                dataSeries.DataPoints.Add(dataPoint);
                if (++i >= 10)
                    break;
            }

            // Add chart to LayoutRoot
            Canvas.SetLeft(chart, 50);
            Canvas.SetTop(chart, 420);
            pageCanvas.Children.Add(chart);
        }

        class DataItem
        {
            public string URL
            {
                get; set;
            }

            public int 综合浏览量
            {
                get; set;
            }

            public string 平均页面停留时间
            {
                get; set;
            }
        };

        void PrintPagePath(Canvas pageCanvas, string profileId, DateTime startDate, DateTime endDate)
        {
            TextBlock title = new TextBlock();

            title.Text = string.Format("{0} 页面访问Top10", endDate.ToLongDateString());
            // Add chart to LayoutRoot
            Canvas.SetLeft(title, 50);
            Canvas.SetTop(title, 420);
            pageCanvas.Children.Add(title);
            // 生成图表
            DataGrid dataGrid = new DataGrid();
            dataGrid.Width = 750;
            dataGrid.Height = 380;

            ObservableCollection<DataItem> items = new ObservableCollection<DataItem>();
            // 生成查询
            DataQuery query = new DataQuery(dataFeedUrl);
            query.Ids = profileId;
            query.Metrics = "ga:pageviews,ga:entrances,ga:timeOnPage";
            query.Dimensions = "ga:pagePath";
            query.Sort = "-ga:pageviews,ga:pagePath";
            query.GAStartDate = endDate.ToString("yyyy-MM-dd");
            query.GAEndDate = endDate.ToString("yyyy-MM-dd");
            query.ExtraParameters = "max-results=10";

            DataFeed dataFeed = service.Query(query);
            List<string> top10URLList = new List<string>();

            foreach (DataEntry entry in dataFeed.Entries)
            {
                DataItem item = new DataItem();
                item.URL = entry.Dimensions[0].Value;
                top10URLList.Add(item.URL);
                item.综合浏览量 = Convert.ToInt32(entry.Metrics[0].Value);
                //item.UserCount = Convert.ToInt32(entry.Metrics[1].Value);
                //item.UserCount = Convert.ToInt32(entry.Metrics[3].Value);
                int t = Convert.ToInt32(Convert.ToDouble(entry.Metrics[2].Value) / Convert.ToDouble(entry.Metrics[0].Value));
                item.平均页面停留时间 = string.Format("{0}:{1}:{2}", t / 3600, (t / 60) % 60, t % 60);
                items.Add(item);
            }

            dataGrid.ItemsSource = items;

            // Add chart to LayoutRoot
            Canvas.SetLeft(dataGrid, 50);
            Canvas.SetTop(dataGrid, 440);
            pageCanvas.Children.Add(dataGrid);

            PrintTop10Detail(profileId, top10URLList, startDate, endDate);
        }

        void PrintTop10Detail(string profileId, List<string> URLList, DateTime startDate, DateTime endDate)
        {
            int i = 1;
            Canvas newPage = null;
            foreach(string URL in URLList)
            {
                if (i % 5 == 1)
                {
                    newPage = AddPage(fixDoc, startDate, endDate);
                    i %= 5;
                }
                PrintURLInfo(newPage, i, profileId, URL, startDate, endDate);
                ++i;
            }
        }

        void PrintURLInfo(Canvas pageCanvas, int index, string profileId, string URL, DateTime startDate, DateTime endDate)
        {

            Chart chart = CreateChart();
            

            Title title = new Title();
            title.Text = string.Format("{0} 的综合访问量", URL);
            chart.Titles.Add(title);

            DataPoint dataPoint;
            DataSeries dataSeries = chart.Series[0];

            // 生成查询
            DataQuery query = new DataQuery(dataFeedUrl);
            query.Ids = profileId;
            query.Metrics = "ga:pageviews";
            query.Dimensions = "ga:date";
            query.Sort = "ga:date";
            query.Filters = "ga:pagePath=~"  + URL;
            query.GAStartDate = startDate.ToString("yyyy-MM-dd");
            query.GAEndDate = endDate.ToString("yyyy-MM-dd");
            query.PrettyPrint = false;

            DataFeed dataFeed = service.Query(query);
            //PageCounts.Clear();
            foreach (DataEntry entry in dataFeed.Entries)
            {
                dataPoint = new DataPoint();
                dataPoint.YValue = Convert.ToDouble(entry.Metrics[0].Value);
                string dt = entry.Dimensions[0].Value;
                dataPoint.XValue = dt.Substring(4, 2) + "月" + dt.Substring(6, 2) + "日";
                dataSeries.DataPoints.Add(dataPoint);
            }

            // Add dataSeries to Series collection.


            // Add chart to LayoutRoot
            Canvas.SetLeft(chart, 50);
            Canvas.SetTop(chart, 100 + (index - 1)* 160);
            pageCanvas.Children.Add(chart);
        }
    }
}
